package Demo;

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

import java.math.BigInteger;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

public class Fenjie {
    public Fenjie() {
    }

    public SortedSet<Integer> getComb(BigInteger wmKey, int n, int k) {
        SortedSet combValue;
        if (wmKey.compareTo(BigInteger.ZERO) >= 0 && wmKey.compareTo(this.combinations(n, k)) < 0) {
            combValue = this.getCombination(wmKey, n, k, 0);
        } else {
            combValue = null;
        }

        return combValue;
    }

    private SortedSet<Integer> getCombination(BigInteger val, int n, int k, int smallest) {
        if (!val.equals(BigInteger.ZERO)) {
            BigInteger c = this.combinations(n - 1, k - 1);
            if (val.compareTo(c) >= 0) {
                return this.getCombination(val.subtract(c), n - 1, k, smallest + 1);
            } else {
                SortedSet<Integer> s = this.getCombination(val, n - 1, k - 1, smallest + 1);
                s.add(new Integer(smallest));
                return s;
            }
        } else {
            SortedSet<Integer> rval = new TreeSet();

            for(int i = 0; i < k; ++i) {
                rval.add(new Integer(smallest + i));
            }

            return rval;
        }
    }

    private BigInteger combinations(int N, int K) {
        BigInteger n = BigInteger.valueOf((long)N);
        BigInteger k = BigInteger.valueOf((long)K);
        BigInteger zero = BigInteger.ZERO;
        BigInteger one = BigInteger.ONE;
        if (k.compareTo(zero) >= 0 && k.compareTo(n) <= 0) {
            BigInteger reflect = n.subtract(k);
            if (k.compareTo(reflect) > 0) {
                k = reflect;
            }

            BigInteger current = one;

            for(BigInteger i = n; i.compareTo(k) > 0; i = i.subtract(one)) {
                current = current.multiply(i);
            }

            current = current.divide(this.factorial(n.subtract(k)));
            return current;
        } else {
            return zero;
        }
    }

    public BigInteger factorial(BigInteger n) {
        if (n.compareTo(BigInteger.ZERO) < 0) {
            throw new IllegalArgumentException("Factorials are defined for n >= 0");
        } else {
            BigInteger rv;
            for(rv = BigInteger.ONE; n.compareTo(BigInteger.ONE) > 0; n = n.subtract(BigInteger.ONE)) {
                rv = rv.multiply(n);
            }

            return rv;
        }
    }

    public BigInteger decodeCombination(Set c, int n) {
        BigInteger sum = BigInteger.ZERO;
        int i = 0;

        for(int found = 0; found < c.size() && i < n; ++i) {
            if (c.contains(new Integer(i))) {
                ++found;
            } else {
                sum = sum.add(this.combinations(n - i - 1, c.size() - found - 1));
            }
        }

        return sum;
    }
}
